﻿#include<stdio.h>

//int main()
//{
//	int a[5] = { 1, 2, 3, 4, 5 };
//	int* ptr = (int*)(&a + 1);
//	//&a表示数组的地址，加一则跨越了整个数组，ptr指向了5后面
//	printf("%d,%d", *(a + 1), *(ptr - 1));
//	//a+1表示a[1]的地址，所以*(a + 1)为a[1]=2
//	//已知&a+1为5后面的地址，减一后就为5的地址，所以结果为5
//	return 0;
//}

//在X86环境下
//假设结构体的⼤⼩是20个字节

//struct Test
//{
//	int Num;
//	char* pcName;
//	short sDate;
//	char cha[2];
//	short sBa[4];
//}*p = (struct Test*)0x100000;
//
//int main()
//{
//	//指针+整数
//	printf("%p\n", p + 0x1);
//	//p的地址为0x100000,加上0x1就等于0x100000+20(因为一个结构体大小为20)，所以等于0x100014
//	printf("%p\n", (unsigned long)p + 0x1);
//	//将p转为整数类型，所以加上0x1就等于加1---------等于0x100001
//	printf("%p\n", (unsigned int*)p + 0x1);
//	//unsigned int*是四个字节，加上0x1就等于0x100004
//	return 0;
//}

//int main()
//{
//	int a[3][2] = { (0, 1), (2, 3), (4, 5) };
//	//这里的数组是三行二列的，但是赋值用的却是()将数据括起来，所以这里是逗号表达式：两个数作比较，取右边的数
//	//所以结果为；
//	//1	3
//	//5	0
//	//0	0
//	int* p;
//	p = a[0];
//	//p指针指向二维数组的第一行
//	printf("%d", p[0]);//这里结果就为第一行数组的第一个元素=1
//	return 0;
//}

//x86环境

//int main()
//{
//	int a[5][5];
//	int(*p)[4];
//	p = a;
//	printf("%p,%d\n", &p[4][2] - &a[4][2], &p[4][2] - &a[4][2]);
//	//&p[4][2] - &a[4][2]=-4：指针-指针=两个指针元素元素的个数
//	//10000000 00000000 00000000 00000100--源码
//	//11111111 11111111 11111111 11111011--反码
//	//11111111 11111111 11111111 11111100--补码
//	//转化为16进制
//	//	FF		 FF		  FF		FC
//	//地址就为0xFFFFFFFC
//	return 0;
//}

//int main()
//{
//	int aa[2][5] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
//	//1 2 3 4 5
//	//6 7 8 9 10
//	int* ptr1 = (int*)(&aa + 1);
//	//&a表示数组的地址，加一则跨越了整个数组，ptr指向了10后面的地址
//	int* ptr2 = (int*)(*(aa + 1));
//	//aa表示数组首元素地址，就是第一行元素的地址，加一就是aa[1]的地址，解引用后就是第二行首元素6
//	printf("%d,%d", *(ptr1 - 1), *(ptr2 - 1));
//	//*(ptr1 - 1)----10
//	// *(ptr2 - 1)---5
//	return 0;
//}

//int main()
//{
//	char* a[] = { "work","at","alibaba" };
//	char** pa = a;
//	//将字符串首元素地址赋值给pa
//	pa++;
//	//pa++，就指向字符串的第二个元素的地址‘a’
//	printf("%s\n", *pa);//at
//	return 0;
//}

//int main()
//{
//	char* c[] = { "ENTER","NEW","POINT","FIRST" };
//	char** cp[] = { c + 3,c + 2,c + 1,c };
//	char*** cpp = cp;
//	printf("%s\n", **++cpp);
//	//cpp指向cp的首元素地址（c+3），加一后，就指向第二个元素(c+2),解引用后，就从c+2的首元素开始打印，结果就为“POINT”
//	//此时cpp指向cp+2==c+2
//	printf("%s\n", *-- * ++cpp + 3);
//	//cpp先+1,就指向cp+3==c+1的地址，解引用后就为c+1，c+1再减一jiu为c
//	//c的首元素加三，就指向'E',结果就为“ER”
//	//此时cpp指向cp+2地址
//	printf("%s\n", *cpp[-2] + 3);
//	//*cpp[-2]==*(cpp-2),这样cpp指向cp的地址，解引用后就为指向c+3的首元素，再加上三就指向‘S’,结果就为‘ST’
//	//此时cpp指向cp+1的地址
//	printf("%s\n", cpp[-1][-1] + 1);
//	//cpp[-1][-1]==*(*(cpp-1)-1),(cpp-1)就等于(cp+1-1)==cp,就是指向c+3的地址，c+3-1==c+2，结果就是指向c+2的首元素的地址，再加上一就从"E"开始打印，就为"EW"
//	return 0;
//}